package com.emerquim.bean.model;

import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.Iterator;
import java.util.List;

import javax.faces.component.UIComponent;
import javax.faces.context.FacesContext;
import javax.faces.event.ActionEvent;

import org.apache.log4j.Logger;
import org.hibernate.HibernateException;

import com.emerquim.bean.support.ControlDespliegue;
import com.emerquim.persistence.dao.EventoDAO;
import com.icesoft.faces.component.ext.HtmlInputHidden;
import com.icesoft.faces.context.effects.JavascriptContext;

/**
 * Clase para consultar un evento de la base de datos
 * @author Felipe Criales
 */
public class ConsultaEvento {

	/**
	 * Funcionalidad de log
	 */
	private static final Logger log = Logger.getLogger(ConsultaEvento.class);

	// ---------------------------------------------
	// Atributos
	// ---------------------------------------------
	
	/**
	 * Atributo para guardar el consecutivo del evento
	 */
	private String consecutivoEvento;
	
	/**
	 * Atributo para guardar la fecha desde del evento
	 */
	private Date fechaDesde;
	
	/**
	 * Atributo para guardar la fecha hasta del evento
	 */
	private Date fechaHasta;
	
	/**
	 * Atributo para guardar el tipo del evento
	 */
	private String tipoEvento;
	
	/**
	 * Atributo que guarda los resultados de la busqueda
	 */
	private List<com.emerquim.persistence.dao.Evento> resultado;
	
	/**
	 * Constructor con parametros
	 * @param consecutivoEvento
	 * @param fechaDesde
	 * @param fechaHasta
	 * @param tipoEvento
	 */
	public ConsultaEvento(String consecutivoEvento, Date fechaDesde,
			Date fechaHasta, String tipoEvento) {
		super();
		this.consecutivoEvento = consecutivoEvento;
		this.fechaDesde = fechaDesde;
		this.fechaHasta = fechaHasta;
		this.tipoEvento = tipoEvento;
		this.resultado = new ArrayList<com.emerquim.persistence.dao.Evento>();
	}
	
	/**
	 * Constructor sin parametros
	 */
	public ConsultaEvento() {	
		inicializarDatos();
	}

	/**
	 * Metodo para inicializar los datos por defecto
	 */
	public void inicializarDatos(){
		Calendar now = Calendar.getInstance();
		this.fechaHasta = now.getTime();
		now.add(Calendar.WEEK_OF_YEAR, -1);
		this.fechaDesde = now.getTime();
		this.resultado = new ArrayList<com.emerquim.persistence.dao.Evento>();
		this.tipoEvento = "T";
		this.consecutivoEvento = "";
	}
	
	/**
	 * Metodo para realizar la busqueda del evento
	 * @author Felipe Criales
	 */
	public void buscarEvento(ActionEvent event){
		System.out.println("Buscar evento");
		
		// 0. Limpiar los resultados anteriores
		this.resultado = new ArrayList<com.emerquim.persistence.dao.Evento>();
		
		// 1. Buscar el evento por el consecutivo si lo tiene
		if(!this.consecutivoEvento.equals("")){
			// 1.1 Convertir el consecutivo a long si puede			
			try {
				Long conLong = Long.parseLong(this.consecutivoEvento);
				EventoDAO eventoDao = new EventoDAO();
				try {
					com.emerquim.persistence.dao.Evento miEvento = new com.emerquim.persistence.dao.Evento();
					miEvento = eventoDao.findById(conLong);
					if(miEvento != null)
						this.resultado.add(miEvento);					
				} catch (HibernateException e) {
					this.enviarMensajeUsuario("Error al consultar un evento de la base de datos");
					eventoDao.getSession().getTransaction().rollback();
					log.error("Error al guardar el evento en la base de datos", e);
				} finally {				
					eventoDao.getSession().close();
				}				
			} catch (NumberFormatException e1) {
				log.error("Erorr al consultar los eventos de la base de datos");
				this.enviarMensajeUsuario("El consecutivo del evento debe ser de tipo numerico");
			}
		}
		
		// 2. Si no tiene el consecutivo buscar por las fechas
		else if(this.fechaDesde != null && this.fechaHasta != null){
			EventoDAO eventoDao = new EventoDAO();
			try {
				List misEventos = eventoDao.findEventoFechasTipo(this.fechaDesde, this.fechaHasta, this.tipoEvento);
				this.resultado.addAll(misEventos);					
			} catch (HibernateException e) {
				this.enviarMensajeUsuario("Error al consultar los eventos de la base de datos");
				eventoDao.getSession().getTransaction().rollback();
				log.error("Erorr al consultar los eventos de la base de datos", e);
			} finally {				
				eventoDao.getSession().close();
			}	
			System.out.println("Buscar los eventos dados las fechas de los eventos");
		}
		
		// 3. Si no se indico la fecha del evento se informa al usuario que indique algo
		else{
			this.enviarMensajeUsuario("Debe llenar los datos para la busqueda de los eventos");
		}		
	}
	

	/**
	 * Metodo para abrir un evento buscado
	 * @author Felipe Criales
	 */
	public void abrirEvento(ActionEvent event){
		try {
			System.out.println("Abrir evento");		
			// 1. Cargar los datos del evento
			UIComponent component = (UIComponent)event.getComponent();
			HtmlInputHidden hiddenIdEvento = (HtmlInputHidden) component.findComponent("hiddenIdEvento");
			Long idEvento = (Long) hiddenIdEvento.getValue();	

			// 2. Cargar la info del evento en la sesion
			Iterator<com.emerquim.persistence.dao.Evento> it = this.resultado.iterator();
			while(it.hasNext()){
				com.emerquim.persistence.dao.Evento miEvento = it.next();

				if(miEvento.getEveId() == idEvento){
					FacesContext context = FacesContext.getCurrentInstance();
					Evento eventoFaces = (Evento) context.getApplication().evaluateExpressionGet(context, "#{evento}", Evento.class);
					eventoFaces.cargarInfoEvento(miEvento);

					// 2.1 Abrir el panel con la info del evento
					ControlDespliegue controlDespliegue = (ControlDespliegue) context.getApplication().evaluateExpressionGet(context, "#{controlDespliegue}", ControlDespliegue.class);
					if(controlDespliegue != null){
						controlDespliegue.setIndexTabPrincipal(0);
						controlDespliegue.getMapaControlDespliegue().put(ControlDespliegue.SUB_VISTA_NUEVO_EVENTO, new Boolean(true));
						controlDespliegue.getMapaControlDespliegue().put(ControlDespliegue.SUB_VISTA_CONSULTAR_EVENTO, null);	
					}
					break;
				}						
			}		

			// 3. Borrar los datos temporales de la busqueda
			inicializarDatos();			
		} catch (Exception e) {
			log.error("No se pudo cargar la informacion del evento", e);
			this.enviarMensajeUsuario("No se pudo consultar el evento");
		}
	}

	
	/**
	 * Metodo para enviar un mensaje de alerta el usuario
	 * @param mensaje
	 * @author Felipe Criales
	 */
	private void enviarMensajeUsuario(String mensaje){
		String funcion = "alert('"+mensaje+"');";
		JavascriptContext.addJavascriptCall(FacesContext
				.getCurrentInstance(), funcion);
	}
	
	/**
	 * @return the consecutivoEvento
	 */
	public String getConsecutivoEvento() {
		return consecutivoEvento;
	}

	/**
	 * @param consecutivoEvento the consecutivoEvento to set
	 */
	public void setConsecutivoEvento(String consecutivoEvento) {
		this.consecutivoEvento = consecutivoEvento;
	}

	/**
	 * @return the fechaDesde
	 */
	public Date getFechaDesde() {
		return fechaDesde;
	}

	/**
	 * @param fechaDesde the fechaDesde to set
	 */
	public void setFechaDesde(Date fechaDesde) {
		this.fechaDesde = fechaDesde;
	}

	/**
	 * @return the fechaHasta
	 */
	public Date getFechaHasta() {
		return fechaHasta;
	}

	/**
	 * @param fechaHasta the fechaHasta to set
	 */
	public void setFechaHasta(Date fechaHasta) {
		this.fechaHasta = fechaHasta;
	}

	/**
	 * @return the tipoEvento
	 */
	public String getTipoEvento() {
		return tipoEvento;
	}

	/**
	 * @param tipoEvento the tipoEvento to set
	 */
	public void setTipoEvento(String tipoEvento) {
		this.tipoEvento = tipoEvento;
	}

	/**
	 * @return the resultado
	 */
	public List<com.emerquim.persistence.dao.Evento> getResultado() {
		return resultado;
	}

	/**
	 * @param resultado the resultado to set
	 */
	public void setResultado(List<com.emerquim.persistence.dao.Evento> resultado) {
		this.resultado = resultado;
	}	
}
